package com.robot.member.service;

import com.alibaba.fastjson.JSON;
import com.robot.member.client.MerchantClient;
import com.robot.member.dao.MerchantApplyDao;
import com.robot.member.pojo.MerchantApply;
import com.robot.member.pojo.client.Store;
import entity.Status;
import entity.StatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import util.BinaryUtil;
import util.CheckUtil;
import util.IdWorker;
import util.UpdateUtil;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 商户入驻申请merchant_apply服务层
 *
 * @author wuyunbin
 */
@Service
public class MerchantApplyService {

    @Autowired
    private MerchantApplyDao merchantApplyDao;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private CheckUtil checkUtil;

    @Autowired
    private MerchantClient merchantClient;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * merchant_apply表status状态 0-初审待审核 1-初审通过 2-初审失败 3-平台待审核 4-平台审核通过 5-平台审核失败
     */
    private String firstTrial = "0";
    private String firstTrialSuccess = "1";
    private String firstTrialFailed = "2";
    private String secondTrial = "3";
    private String secondTrialSuccess = "4";
    private String secondTrialFailed = "5";

    /**
     * 查询全部列表
     *
     * @return
     */
    public List<MerchantApply> findAll() {
        return merchantApplyDao.findAll();
    }


    /**
     * 条件查询+分页
     *
     * @param whereMap
     * @param page
     * @param size
     * @return
     */
    public Page<MerchantApply> findSearch(Map whereMap, int page, int size) {
        Specification<MerchantApply> specification = createSpecification(whereMap);
        PageRequest pageRequest = PageRequest.of(page - 1, size);
        return merchantApplyDao.findAll(specification, pageRequest);
    }


    /**
     * 条件查询
     *
     * @param whereMap
     * @return
     */
    public List<MerchantApply> findSearch(Map whereMap) {
        Specification<MerchantApply> specification = createSpecification(whereMap);
        return merchantApplyDao.findAll(specification);
    }

    /**
     * 根据ID查询实体
     *
     * @param id
     * @return
     */
    public MerchantApply findById(String id) {
        return merchantApplyDao.findById(id).orElse(null);
    }

    /**
     * 增加
     *
     * @param apply
     */
    public void add(MerchantApply apply) {
        apply.setId(BinaryUtil.decimal2Base62(idWorker.nextId()));
        apply.setCompanyId(BinaryUtil.decimal2Base62(idWorker.nextId()));
        apply.setStoreId(BinaryUtil.decimal2Base62(idWorker.nextId()));
        apply.setStatus("0");
        LocalDateTime now = LocalDateTime.now();
        apply.setCreatedAt(now);
        apply.setUpdatedAt(now);
        merchantApplyDao.save(apply);
    }

    /**
     * 修改
     *
     * @param apply
     */
    public void update(MerchantApply apply) {
        apply.setUpdatedAt(LocalDateTime.now());
        merchantApplyDao.save(apply);
    }

    public void update(MerchantApply src, MerchantApply target) {
        UpdateUtil.copyNonNullProperties(src, target);
        logger.info(src.toString());
        logger.info(target.toString());
    }

    /**
     * 删除
     *
     * @param id
     */
    public void deleteById(String id) {
        merchantApplyDao.deleteById(id);
    }

    /**
     * 动态条件构建
     *
     * @param searchMap
     * @return
     */
    private Specification<MerchantApply> createSpecification(Map searchMap) {
        return (Specification<MerchantApply>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<Predicate>();
            // 商家申请表id
            String id = "id";
            if (searchMap.get(id) != null && !"".equals(searchMap.get(id))) {
                predicateList.add(cb.like(root.get(id).as(String.class), "%" + (String) searchMap.get(id) + "%"));
            }
            // 会员id
            String memberId = "memberId";
            if (searchMap.get(memberId) != null && !"".equals(searchMap.get(memberId))) {
                predicateList.add(cb.like(root.get(memberId).as(String.class), "%" + (String) searchMap.get(memberId) + "%"));
            }
            // 商家id
            String companyId = "companyId";
            if (searchMap.get(companyId) != null && !"".equals(searchMap.get(companyId))) {
                predicateList.add(cb.like(root.get(companyId).as(String.class), "%" + (String) searchMap.get(companyId) + "%"));
            }
            // 店铺id
            String storeId = "storeId";
            if (searchMap.get(storeId) != null && !"".equals(searchMap.get(storeId))) {
                predicateList.add(cb.like(root.get(storeId).as(String.class), "%" + (String) searchMap.get(storeId) + "%"));
            }
            // 公司名字
            String companyName = "companyName";
            if (searchMap.get(companyName) != null && !"".equals(searchMap.get(companyName))) {
                predicateList.add(cb.like(root.get(companyName).as(String.class), "%" + (String) searchMap.get(companyName) + "%"));
            }
            // 联系人
            String contract = "contract";
            if (searchMap.get(contract) != null && !"".equals(searchMap.get(contract))) {
                predicateList.add(cb.like(root.get(contract).as(String.class), "%" + (String) searchMap.get(contract) + "%"));
            }
            // 身份证号码
            String idCard = "idCard";
            if (searchMap.get(idCard) != null && !"".equals(searchMap.get(idCard))) {
                predicateList.add(cb.like(root.get(idCard).as(String.class), "%" + (String) searchMap.get(idCard) + "%"));
            }
            // 联系电话
            String phone = "phone";
            if (searchMap.get(phone) != null && !"".equals(searchMap.get(phone))) {
                predicateList.add(cb.like(root.get(phone).as(String.class), "%" + (String) searchMap.get(phone) + "%"));
            }
            // 邮箱
            String email = "email";
            if (searchMap.get(email) != null && !"".equals(searchMap.get(email))) {
                predicateList.add(cb.like(root.get(email).as(String.class), "%" + (String) searchMap.get(email) + "%"));
            }
            // 行业id
            String industryId = "industryId";
            if (searchMap.get(industryId) != null && !"".equals(searchMap.get(industryId))) {
                predicateList.add(cb.like(root.get(industryId).as(String.class), "%" + (String) searchMap.get(industryId) + "%"));
            }
            // 行业许可证编号
            String industryLicense = "industryLicense";
            if (searchMap.get(industryLicense) != null && !"".equals(searchMap.get(industryLicense))) {
                predicateList.add(cb.like(root.get(industryLicense).as(String.class), "%" + (String) searchMap.get(industryLicense) + "%"));
            }
            // 行业
            String industry = "industry";
            if (searchMap.get(industry) != null && !"".equals(searchMap.get(industry))) {
                predicateList.add(cb.like(root.get(industry).as(String.class), "%" + (String) searchMap.get(industry) + "%"));
            }
            // 省份
            String province = "province";
            if (searchMap.get(province) != null && !"".equals(searchMap.get(province))) {
                predicateList.add(cb.like(root.get(province).as(String.class), "%" + (String) searchMap.get(province) + "%"));
            }
            // 省份id
            String provinceId = "provinceId";
            if (searchMap.get(provinceId) != null && !"".equals(searchMap.get(provinceId))) {
                predicateList.add(cb.like(root.get(provinceId).as(String.class), "%" + (String) searchMap.get(provinceId) + "%"));
            }
            // 城市
            String city = "city";
            if (searchMap.get(city) != null && !"".equals(searchMap.get(city))) {
                predicateList.add(cb.like(root.get(city).as(String.class), "%" + (String) searchMap.get(city) + "%"));
            }
            // 城市id
            String cityId = "cityId";
            if (searchMap.get(cityId) != null && !"".equals(searchMap.get(cityId))) {
                predicateList.add(cb.like(root.get(cityId).as(String.class), "%" + (String) searchMap.get(cityId) + "%"));
            }
            // 区县
            String area = "area";
            if (searchMap.get(area) != null && !"".equals(searchMap.get(area))) {
                predicateList.add(cb.like(root.get(area).as(String.class), "%" + (String) searchMap.get(area) + "%"));
            }
            // 区县id
            String areaId = "areaId";
            if (searchMap.get(areaId) != null && !"".equals(searchMap.get(areaId))) {
                predicateList.add(cb.like(root.get(areaId).as(String.class), "%" + (String) searchMap.get(areaId) + "%"));
            }
            // 详细地址
            String address = "address";
            if (searchMap.get(address) != null && !"".equals(searchMap.get(address))) {
                predicateList.add(cb.like(root.get(address).as(String.class), "%" + (String) searchMap.get(address) + "%"));
            }
            // 营业执照号码
            String businessLicense = "businessLicense";
            if (searchMap.get(businessLicense) != null && !"".equals(searchMap.get(businessLicense))) {
                predicateList.add(cb.like(root.get(businessLicense).as(String.class), "%" + (String) searchMap.get(businessLicense) + "%"));
            }
            // 推荐人id
            String recommendId = "recommendId";
            if (searchMap.get(recommendId) != null && !"".equals(searchMap.get(recommendId))) {
                predicateList.add(cb.like(root.get(recommendId).as(String.class), "%" + (String) searchMap.get(recommendId) + "%"));
            }
            // 状态 0-初审待审核 1-初审通过 2-平台审核失败 3-平台待审核 4-平台审核通过 5-平台审核失败
            String status = "status";
            if (searchMap.get(status) != null && !"".equals(searchMap.get(status))) {
                predicateList.add(cb.like(root.get(status).as(String.class), "%" + (String) searchMap.get(status) + "%"));
            }
            // 备注
            String remark = "remark";
            if (searchMap.get(remark) != null && !"".equals(searchMap.get(remark))) {
                predicateList.add(cb.like(root.get(remark).as(String.class), "%" + (String) searchMap.get(remark) + "%"));
            }
            //剔除软删除数据
            String deletedAt = "deletedAt";
            predicateList.add(cb.equal(root.get(deletedAt), cb.nullLiteral(LocalDateTime.class)));

            return cb.and(predicateList.toArray(new Predicate[predicateList.size()]));
        };
    }

    /**
     * 通过storeId查询merchant_apply详情
     *
     * @param storeId
     * @return
     */
    public MerchantApply findTopByStoreIdOrderByUpdatedAtDesc(String storeId) {
        return merchantApplyDao.findTopByStoreIdOrderByUpdatedAtDesc(storeId);
    }

    /**
     * 通过memberId和deletedAt查询merchant_apply列表
     *
     * @param memberId
     * @param page
     * @param size
     * @return
     */
    public Page<MerchantApply> findAllByMemberIdAndDeletedAtIsNullOrderByUpdatedAtDesc(String memberId, int page, int size) {
        Pageable pageable = PageRequest.of(page - 1, size);
        return merchantApplyDao.findAllByMemberIdAndDeletedAtIsNullOrderByUpdatedAtDesc(memberId, pageable);
    }

    /**
     * 通过areaId查询merchant_apply列表
     *
     * @param areaId
     * @return
     */
    public List<MerchantApply> findAllByAreaIdAndDeletedAtIsNullOrderByUpdatedAtDesc(String areaId) {
        return merchantApplyDao.findAllByAreaIdAndDeletedAtIsNullOrderByUpdatedAtDesc(areaId);
    }

    /**
     * 通过areaId和status查询merchant_apply列表
     *
     * @param areaId
     * @param status
     * @return
     */
    public List<MerchantApply> findAllByAreaIdAndStatusAndDeletedAtIsNullOrderByUpdatedAtDesc(String areaId, String status) {
        return merchantApplyDao.findAllByAreaIdAndStatusAndDeletedAtIsNullOrderByUpdatedAtDesc(areaId, status);
    }

    /**
     * 通过id和memberId查询merchant_apply详情
     *
     * @param id
     * @param memberId
     * @return
     */
    public MerchantApply findByIdAndMemberIdAndDeletedAtIsNull(String id, String memberId) {
        return merchantApplyDao.findByIdAndMemberIdAndDeletedAtIsNull(id, memberId);
    }

    /**
     * 通过phone查询merchant_apply列表
     *
     * @param phone
     * @return
     */
    public List<MerchantApply> findAllByPhone(String phone) {
        return merchantApplyDao.findAllByPhone(phone);
    }


    public MerchantApply findSecondTrialApplyByIdAndMemberIdAndStatus(String id, String memberId) {
        return merchantApplyDao.findByIdAndMemberIdAndStatusAndDeletedAtIsNull(id, memberId, firstTrialSuccess);
    }

    /**
     * 检验申请表基础信息(提交给合伙人)
     *
     * @param apply
     * @return
     */
    public Status checkBaseInfo(MerchantApply apply) {

        String isChain = "1";
        if (apply.getStoreName() == null || "".equals(apply.getStoreName())) {
            return StatusCode.ERROR_STORE_NAME_REQUIRED;
        }
        if (isChain.equals(apply.getIsChain())) {
            if (apply.getCompanyName() == null || "".equals(apply.getCompanyName())) {
                return StatusCode.ERROR_COMPANY_NAME_REQUIRED;
            }
        } else {
            apply.setCompanyName(apply.getStoreName());
            apply.setIsChain("0");
        }

        if (apply.getContract() == null || "".equals(apply.getContract())) {
            return StatusCode.ERROR_CONTACT_REQUIRED;
        }

        if (apply.getProvince() == null || "".equals(apply.getProvince())) {
            return StatusCode.ERROR_PROVINCE_REQUIRED;
        }
        if (apply.getCityId() == null || "".equals(apply.getCityId())) {
            return StatusCode.ERROR_CITY_REQUIRED;
        }
        if (apply.getAreaId() == null || "".equals(apply.getAreaId())) {
            return StatusCode.ERROR_AREA_REQUIRED;
        }
        if (apply.getProvinceId() == null || "".equals(apply.getProvinceId())) {
            return StatusCode.ERROR_PROVINCE_REQUIRED;
        }
        if (apply.getCity() == null || "".equals(apply.getCity())) {
            return StatusCode.ERROR_CITY_REQUIRED;
        }
        if (apply.getArea() == null || "".equals(apply.getArea())) {
            return StatusCode.ERROR_AREA_REQUIRED;
        }

        if (apply.getAddress() == null || "".equals(apply.getAddress())) {
            return StatusCode.ERROR_ADDRESS_REQUIRED;
        }

        if (apply.getPhone() == null || "".equals(apply.getPhone())) {
            return StatusCode.ERROR_PHONE_REQUIRED;
        }

        if (!checkUtil.checkPhone(apply.getPhone())) {
            return StatusCode.ERROR_INVALID_PHONE;
        }

        //判断手机号是否已被其他会员申请入驻使用
        List<MerchantApply> merchantApplyList = findAllByPhone(apply.getPhone());
        if (merchantApplyList.size() != 0) {
            return StatusCode.ERROR_DUPLICATE_PHONE;
        }
        //判断手机号是否已被店铺使用
        Store storeInDb = JSON.parseObject(merchantClient.thirdFindStoreByPhone(apply.getPhone()), Store.class);
        logger.info("判断手机号是否唯一" + storeInDb);
        if (storeInDb != null) {
            return StatusCode.ERROR_DUPLICATE_PHONE;
        }

        if (apply.getIndustryId() == null || "".equals(apply.getIndustryId())) {
            return (StatusCode.ERROR_INDUSTRYID_REQUIRED);
        }

        return null;
    }

    /**
     * 判断手机号
     *
     * @param phone
     * @return
     */
    public Status checkPhoneUsed(String phone) {
        if (!checkUtil.checkPhone(phone)) {
            return StatusCode.ERROR_INVALID_PHONE;
        }
        //判断手机号是否已被其他会员申请入驻使用
        List<MerchantApply> merchantApplyList = findAllByPhone(phone);
        if (merchantApplyList.size() != 0) {
            return StatusCode.ERROR_DUPLICATE_PHONE;
        }
        //判断手机号是否已被店铺使用
        Store storeInDb = JSON.parseObject(merchantClient.thirdFindStoreByPhone(phone), Store.class);
        logger.info("判断手机号是否唯一" + storeInDb);
        if (storeInDb != null) {
            return StatusCode.ERROR_DUPLICATE_PHONE;
        }
        return null;
    }

    /**
     * 检查会员补充的信息
     *
     * @param apply
     * @return
     */
    public Status checkApply(MerchantApply apply) {

        //检查邮件
        if (apply.getEmail() == null || "".equals(apply.getEmail())) {
            return StatusCode.ERROR_EMAIL_REQUIRED;
        }

        if (checkUtil.checkEmail(apply.getEmail())) {
            return StatusCode.ERROR_INVALID_EMAIL;
        }
        //检查身份证国徽页
        if (apply.getIdCardFront() == null || "".equals(apply.getIdCardFront())) {
            return StatusCode.ERROR_ID_CARD_FRONT_REQUIRED;
        }

        if (!checkUtil.checkImage(apply.getIdCardFront())) {
            return StatusCode.ERROR_FILE_FORMAT;
        }
        //检查身份证个人信息页
        if (apply.getIdCardBack() == null || "".equals(apply.getIdCardBack())) {
            return StatusCode.ERROR_ID_CARD_BACK_REQUIRED;
        }
        if (!checkUtil.checkImage(apply.getIdCardBack())) {
            return StatusCode.ERROR_FILE_FORMAT;
        }

        //行业许可
        if (apply.getIndustryLicenseImg() == null || "".equals(apply.getIndustryLicenseImg())) {
            return StatusCode.ERROR_FILE_MISSING;
        }
        if (!checkUtil.checkImage(apply.getIndustryLicenseImg())) {
            return StatusCode.ERROR_FILE_FORMAT;
        }
        //营业执照
        if (apply.getBusinessLicenseImg() == null || "".equals(apply.getBusinessLicenseImg())) {
            return StatusCode.ERROR_FILE_FORMAT;
        }

        if (!checkUtil.checkImage(apply.getBusinessLicenseImg())) {
            return StatusCode.ERROR_FILE_FORMAT;
        }

        //门头照
        if (apply.getCoverImage() == null || "".equals(apply.getCoverImage())) {
            return StatusCode.ERROR_COVER_IMAGE_REQUIRED;
        }

        if (!checkUtil.checkImage(apply.getCoverImage())) {
            return StatusCode.ERROR_FILE_FORMAT;
        }
        //店内照
        String images = apply.getImages();
        if (images == null || "".equals(images)) {
            return StatusCode.ERROR_IMAGES_REQUIRED;
        }

        String[] imagesArray = images.split(",");

        for (String image : imagesArray) {
            if (!checkUtil.checkImage(image)) {
                return StatusCode.ERROR_FILE_FORMAT;
            }
        }

        return null;
    }

}
